# -*- shell-script -*-

# 07device - Device scanning routines and variables.

# This file is part of the Linux lsvpd package.

# (C) Copyright IBM Corp. 2002, 2003, 2004, 2005

# Maintained by  Martin Schwenke <martins@au.ibm.com>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.
 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    
# $Id: 07device,v 1.1 2006/04/11 18:38:28 emunson Exp $

# Default and common functions.

# This module is always loaded.
true || return 0

######################################################################

list_devices ()
{
    # Sets: device_list
    device_list=$(node_handler "list_nodes")
}

get_names_device ()
{
    # Sets: names

    local bus_type="$1"
    local bus_addr="$2"

    names=$(node_handler "get_name" "$bus_type" "${bus_type}/${bus_addr}")
}

device_get_parent_name ()
{
    # Sets: parent_name

    local bus_type="$1"
    local bus_addr="$2"

    device_get_parent_name_basic "$bus_type" "$bus_addr"
}

device_get_parent_name_basic ()
{
    # Sets: parent_name

    local bus_type="$1"
    local bus_addr="$2"

    parent_name=$(node_handler "get_parent_name" "$bus_type" "${bus_type}/${bus_addr}")
}

retrieve_vpd_device ()
{
    local bus_type="$1"
    local bus_info="$2"
    local tmp_dir="$3"

    debug_cmd node_handler "get_vpd" "$bus_type" "$bus_info" "$tmp_dir"
}

######################################################################

get_parent_node_device ()
{
    # Sets: parent_node
    parent_node=""

    local bus_type="$1"
    local bus_addr="$2"

    local bus_alias
    bus_alias_get "${bus_type}/${bus_addr}" "parent-node"
    parent_node="$bus_alias"

    [ -n "$parent_node" ] && return 0 ### !!!

    local parent_name
    device_get_parent_name "$bus_type" "$bus_addr"
    [ -n "$parent_name" ] || return 1

    # FIXME: gross hack
    case "$parent_name" in
	(usb*) bus_type="usb" ;;
    esac

    local os_subdir
    get_os_subdir "adapter" "$bus_type"

    local try="${db_os_dir}/adapter/${os_subdir}/${parent_name}"
    case "$bus_type" in
	scsi)
	    local host bus target lun
	    scsi_parse_addr_hook "$bus_addr"
	    try="${try}:${bus} ${try}"
	    ;;
    esac

    local t
    for t in $try ; do
	l="${t}/bus-node"
	if [ -L "$l" ] && cd -P "$l" ; then
	    parent_node="$PWD"
	    cd "$OLDPWD"
	    bus_alias_set "${bus_type}/${bus_addr}" \
		"$parent_node" "parent-node"
	    return 0
	fi
    done

    return 1
}

get_parent_subtype_device ()
{
    # Sets: parent_subtype
    parent_subtype=""

    local bus_type="$1"
    local bus_addr="$2"

    local parent_node
    get_parent_node "device" "$bus_type" "$bus_addr"

    local subtype
    retrieve_subtype_basic "$parent_node"
    parent_subtype="$subtype"
}

######################################################################

device_set_adapter_yl ()
{
    # Sets: adapter_yl
    adapter_yl=""

    local source_node="$1"
    local node="$2"

    local yl
    local l="${node}/lsvpd,parent-node"

    if [ -L "$l" ] ; then
	cd -P "$l"
	local parent_node="$PWD"
	cd "$OLDPWD"

	local f="${parent_node}/lsvpd,bus-info"
	if [ -r "$f" ] ; then
	    local bus_info
	    read bus_info <"$f"
	    if [ -n "$bus_info" ] ; then
		local parent_type="${bus_info%/*}"
		local parent_addr="${bus_info#*/}"

		local source_node
		adapter_get_source_node "$parent_type" "$parent_addr" "unknown"
		get_yl "adapter" "$parent_type" "$parent_addr" \
		    "$source_node" "$parent_node"
		adapter_yl="$yl"
	    fi
	fi
    fi
}

######################################################################

scsi_parse_addr_hook ()
{
    local scsi_addr="$1" # host:bus:target:lun

    # Sets: host, bus, target, lun

    local bustarget="${scsi_addr#*:}"
    bustarget="${bustarget%:*}"

    host="${scsi_addr%%:*}"
    bus="${bustarget%:*}"
    target="${bustarget#*:}"
    lun="${scsi_addr##*:}"
}

######################################################################

names_to_ax_device ()
{
    # Sets: ax
    ax=""

    local subtype="$1"
    local names="$2"

    # FIXME: This is true for now.  That is, only ever one name, so take 1st.
    ax="${names%% *}"
}
